package com.fsserver.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fsserver.common.constants.PaymentConstants;
import com.fsserver.common.exception.BusinessException;
import com.fsserver.core.dto.PaymentRequestDTO;
import com.fsserver.core.entity.PaymentOrder;
import com.fsserver.core.entity.PaymentTransaction;
import com.fsserver.core.mapper.PaymentTransactionMapper;
import com.fsserver.core.service.PaymentOrderService;
import com.fsserver.core.service.PaymentService;
import com.fsserver.core.service.PaymentStrategy;
import com.fsserver.core.vo.PaymentResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 支付服务实现类
 * Payment Service Implementation
 *
 * @author fsserver
 */
@Slf4j
@Service
public class PaymentServiceImpl extends BaseServiceImpl<PaymentTransactionMapper, PaymentTransaction> implements PaymentService {

    @Autowired
    private PaymentOrderService paymentOrderService;

    @Autowired
    private Map<String, PaymentStrategy> paymentStrategyMap;

    /**
     * 创建支付
     * Create payment
     *
     * @param paymentRequestDTO 支付请求DTO
     * @return 支付响应
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PaymentResponseVO createPayment(PaymentRequestDTO paymentRequestDTO) {
        log.info("创建支付: {}", paymentRequestDTO);
        
        // 获取支付订单
        PaymentOrder paymentOrder = paymentOrderService.getOrderByOrderNo(paymentRequestDTO.getOrderNo());
        if (paymentOrder == null) {
            log.error("支付订单不存在: {}", paymentRequestDTO.getOrderNo());
            throw new BusinessException("支付订单不存在");
        }
        
        // 检查订单状态
        if (!PaymentConstants.PaymentStatus.INIT.equals(paymentOrder.getStatus())) {
            log.error("支付订单状态不允许支付: {}, {}", paymentRequestDTO.getOrderNo(), paymentOrder.getStatus());
            throw new BusinessException("支付订单状态不允许支付");
        }
        
        // 检查订单是否过期
        if (paymentOrder.getExpirationTime() != null && paymentOrder.getExpirationTime().before(new Date())) {
            log.error("支付订单已过期: {}", paymentRequestDTO.getOrderNo());
            throw new BusinessException("支付订单已过期");
        }
        
        // 获取支付策略
        PaymentStrategy paymentStrategy = getPaymentStrategy(paymentRequestDTO.getPaymentType());
        
        // 创建支付交易
        PaymentTransaction paymentTransaction = createPaymentTransaction(paymentOrder, paymentRequestDTO);
        
        // 更新订单状态
        paymentOrderService.updateOrderStatus(paymentOrder.getOrderNo(), PaymentConstants.PaymentStatus.PROCESSING);
        
        // 调用支付策略创建支付
        PaymentResponseVO paymentResponseVO = paymentStrategy.createPayment(paymentRequestDTO, paymentTransaction);
        
        log.info("支付创建成功: {}, {}", paymentRequestDTO.getOrderNo(), paymentRequestDTO.getPaymentType());
        return paymentResponseVO;
    }

    /**
     * 查询支付
     * Query payment
     *
     * @param orderNo     订单号
     * @param paymentType 支付类型
     * @return 支付交易
     */
    @Override
    public PaymentTransaction queryPayment(String orderNo, String paymentType) {
        log.info("查询支付: {}, {}", orderNo, paymentType);
        
        // 获取支付交易
        PaymentTransaction paymentTransaction = getPaymentTransaction(orderNo, paymentType);
        if (paymentTransaction == null) {
            log.error("支付交易不存在: {}, {}", orderNo, paymentType);
            throw new BusinessException("支付交易不存在");
        }
        
        // 获取支付策略
        PaymentStrategy paymentStrategy = getPaymentStrategy(paymentType);
        
        // 调用支付策略查询支付
        PaymentTransaction updatedTransaction = paymentStrategy.queryPayment(orderNo, paymentTransaction.getTransactionNo());
        
        // 更新支付交易
        if (updatedTransaction != null && !paymentTransaction.getStatus().equals(updatedTransaction.getStatus())) {
            // 更新支付交易状态
            updateById(updatedTransaction);
            
            // 更新订单状态
            if (PaymentConstants.PaymentStatus.SUCCESS.equals(updatedTransaction.getStatus())) {
                paymentOrderService.updateOrderStatus(orderNo, PaymentConstants.PaymentStatus.SUCCESS);
            } else if (PaymentConstants.PaymentStatus.FAILED.equals(updatedTransaction.getStatus())) {
                paymentOrderService.updateOrderStatus(orderNo, PaymentConstants.PaymentStatus.FAILED);
            }
            
            return updatedTransaction;
        }
        
        return paymentTransaction;
    }

    /**
     * 关闭支付
     * Close payment
     *
     * @param orderNo     订单号
     * @param paymentType 支付类型
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean closePayment(String orderNo, String paymentType) {
        log.info("关闭支付: {}, {}", orderNo, paymentType);
        
        // 获取支付交易
        PaymentTransaction paymentTransaction = getPaymentTransaction(orderNo, paymentType);
        if (paymentTransaction == null) {
            log.error("支付交易不存在: {}, {}", orderNo, paymentType);
            return false;
        }
        
        // 检查交易状态
        if (!PaymentConstants.PaymentStatus.INIT.equals(paymentTransaction.getStatus()) && 
            !PaymentConstants.PaymentStatus.PROCESSING.equals(paymentTransaction.getStatus())) {
            log.error("支付交易状态不允许关闭: {}, {}, {}", orderNo, paymentType, paymentTransaction.getStatus());
            return false;
        }
        
        // 获取支付策略
        PaymentStrategy paymentStrategy = getPaymentStrategy(paymentType);
        
        // 调用支付策略关闭支付
        boolean result = paymentStrategy.closePayment(orderNo, paymentTransaction.getTransactionNo());
        
        if (result) {
            // 更新支付交易状态
            paymentTransaction.setStatus(PaymentConstants.PaymentStatus.CLOSED);
            updateById(paymentTransaction);
            
            // 关闭支付订单
            paymentOrderService.closeOrder(orderNo);
        }
        
        log.info("支付关闭结果: {}, {}, {}", orderNo, paymentType, result);
        return result;
    }

    /**
     * 处理支付通知
     * Handle payment notification
     *
     * @param paymentType 支付类型
     * @param params      通知参数
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handlePaymentNotification(String paymentType, Map<String, String> params) {
        log.info("处理支付通知: {}, {}", paymentType, params);
        
        // 获取支付策略
        PaymentStrategy paymentStrategy = getPaymentStrategy(paymentType);
        
        // 调用支付策略处理支付通知
        PaymentTransaction paymentTransaction = paymentStrategy.handlePaymentNotification(params);
        
        if (paymentTransaction != null) {
            // 获取原支付交易
            PaymentTransaction originalTransaction = getOne(new LambdaQueryWrapper<PaymentTransaction>()
                    .eq(PaymentTransaction::getTransactionNo, paymentTransaction.getTransactionNo()));
            
            if (originalTransaction != null) {
                // 更新支付交易
                paymentTransaction.setId(originalTransaction.getId());
                updateById(paymentTransaction);
                
                // 更新订单状态
                if (PaymentConstants.PaymentStatus.SUCCESS.equals(paymentTransaction.getStatus())) {
                    paymentOrderService.updateOrderStatus(paymentTransaction.getOrderNo(), PaymentConstants.PaymentStatus.SUCCESS);
                } else if (PaymentConstants.PaymentStatus.FAILED.equals(paymentTransaction.getStatus())) {
                    paymentOrderService.updateOrderStatus(paymentTransaction.getOrderNo(), PaymentConstants.PaymentStatus.FAILED);
                }
                
                log.info("支付通知处理成功: {}, {}", paymentType, paymentTransaction.getTransactionNo());
                return true;
            }
        }
        
        log.error("支付通知处理失败: {}", paymentType);
        return false;
    }
    
    /**
     * 创建支付交易
     * Create payment transaction
     *
     * @param paymentOrder      支付订单
     * @param paymentRequestDTO 支付请求DTO
     * @return 支付交易
     */
    private PaymentTransaction createPaymentTransaction(PaymentOrder paymentOrder, PaymentRequestDTO paymentRequestDTO) {
        // 检查是否已存在支付交易
        PaymentTransaction existingTransaction = getPaymentTransaction(paymentOrder.getOrderNo(), paymentRequestDTO.getPaymentType());
        if (existingTransaction != null) {
            // 如果已存在且状态为初始化或处理中，则返回已存在的交易
            if (PaymentConstants.PaymentStatus.INIT.equals(existingTransaction.getStatus()) || 
                PaymentConstants.PaymentStatus.PROCESSING.equals(existingTransaction.getStatus())) {
                return existingTransaction;
            }
        }
        
        // 创建新的支付交易
        PaymentTransaction paymentTransaction = new PaymentTransaction();
        paymentTransaction.setOrderNo(paymentOrder.getOrderNo());
        paymentTransaction.setTransactionNo(generateTransactionNo());
        paymentTransaction.setPaymentType(paymentRequestDTO.getPaymentType());
        paymentTransaction.setAmount(paymentOrder.getAmount());
        paymentTransaction.setCurrency(paymentOrder.getCurrency());
        paymentTransaction.setStatus(PaymentConstants.PaymentStatus.INIT);
        paymentTransaction.setUserId(paymentOrder.getUserId());
        paymentTransaction.setUserName(paymentOrder.getUserName());
        paymentTransaction.setUserIp(paymentRequestDTO.getUserIp());
        
        // 保存支付交易
        save(paymentTransaction);
        
        return paymentTransaction;
    }
    
    /**
     * 获取支付交易
     * Get payment transaction
     *
     * @param orderNo     订单号
     * @param paymentType 支付类型
     * @return 支付交易
     */
    private PaymentTransaction getPaymentTransaction(String orderNo, String paymentType) {
        return getOne(new LambdaQueryWrapper<PaymentTransaction>()
                .eq(PaymentTransaction::getOrderNo, orderNo)
                .eq(PaymentTransaction::getPaymentType, paymentType)
                .orderByDesc(PaymentTransaction::getCreateTime)
                .last("LIMIT 1"));
    }
    
    /**
     * 获取支付策略
     * Get payment strategy
     *
     * @param paymentType 支付类型
     * @return 支付策略
     */
    private PaymentStrategy getPaymentStrategy(String paymentType) {
        PaymentStrategy paymentStrategy = paymentStrategyMap.get(paymentType);
        if (paymentStrategy == null) {
            log.error("支付类型不支持: {}", paymentType);
            throw new BusinessException("支付类型不支持");
        }
        return paymentStrategy;
    }
    
    /**
     * 生成交易号
     * Generate transaction number
     *
     * @return 交易号
     */
    private String generateTransactionNo() {
        // 生成交易号：时间戳 + 6位随机数
        return "T" + System.currentTimeMillis() + String.format("%06d", (int) (Math.random() * 1000000));
    }
} 